package com.szholly.plug.form.core;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONNull;
import net.sf.json.JSONObject;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.jdbc.UncategorizedSQLException;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.util.UrlPathHelper;

import com.szholly.utils.session.SessionFactory;
import com.szholly.utils.session.provider.ISessionProvider;
import com.szholly.utils.spring.SpringBeanFactory;
import com.szholly.utils.util.PinYinUtil;
import com.szholly.utils.util.StringUtils;
import com.szholly.utils.util.TreeDataNode;
import com.szholly.data.common.util.ConvertCaptionUtils;
import com.szholly.data.common.util.TreeDataUtils;
import com.szholly.data.general.*;
import com.szholly.data.general.interceptor.DbEditType;
import com.szholly.data.general.interceptor.defulat.UniqueCheckException;
import com.szholly.data.general.interceptor.defulat.VersionCheckException;
import com.szholly.plug.form.core.interceptor.FormEditInterceptorClass;
import com.szholly.plug.form.validation.FieldIsNullException;
import com.szholly.plug.form.validation.RegexNotMatchException;
import com.szholly.plug.form.validation.StringLengthException;
import com.szholly.plug.safe.entity.user.UserEntity;

/**
 * 定义表单通用处理服务器
 */
@Component
public class FormHandler implements HandlerAdapter {

	@Autowired
	private UrlPathHelper urlHelper;

	/**
	 * 保存数据
	 *
	 * @param tableName
	 *            数据表名
	 * @param row
	 *            记录，Json格式
	 * @throws Exception
	 */
	public String save(String tableName, String row) throws Exception {
		if (StringUtils.IsNullOrSpace(tableName)
				|| StringUtils.IsNullOrSpace(row)) {
			return "";
		}
		tableName = tableName.toUpperCase();

		ObjectMapper mapper = new ObjectMapper();
		try {
			JsonNode rootNode = mapper.readTree(row);
			RowBase entity = mapper.readValue(rootNode, RowBase.class);
			setChildTable(mapper, rootNode, entity);

			Object obj = entity.getValue("_IS_DOMAIN_TRUE");
			if(obj!=null && obj.toString().toLowerCase().equals("true")){
				return saveDomain(tableName, entity);
			}else{
				return tableSave(tableName, entity);
			}
		} catch (Exception e) {
			throw e;
		}
	}

	private void setChildTable(ObjectMapper mapper, JsonNode rootNode, RowBase entity) throws JsonParseException, JsonMappingException, IOException{
		JsonNode childNode = rootNode.get("childValues");
		if(childNode!=null){
			Iterator<String> fieldNames = childNode.getFieldNames();
			while(fieldNames.hasNext()){
				String childTable = fieldNames.next();
				JsonNode childRowListNode = childNode.get(childTable);
				Iterator<JsonNode> rowListNode = childRowListNode.getElements();
				List<RowBase> cRowList = new ArrayList<RowBase>();
				while(rowListNode.hasNext()){
					JsonNode rowNode = rowListNode.next();
					RowBase cRow = mapper.readValue(rowNode, RowBase.class);
					cRowList.add(cRow);

					setChildTable(mapper, rowNode, cRow);
				}
				if(entity.getChildValues()==null){
					entity.setChildValues(new HashMap<String, List<RowBase>>());
				}
				entity.getChildValues().put(childTable, cRowList);
			}
		}
	}

	private String tableSave(String tableName, RowBase entity) throws Exception {
		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);

		String returnString = FormEditInterceptorClass.BeforeDbEditOptionEx(pTable, entity, DbEditType.Insert);
		if(StringUtils.IsNullOrSpace(returnString)){
			pTable.startEditing();
//			BpmTransactionManager.singleRef.StartTransactions();
			try{
				pTable.save(entity);

				// 再做一次字典转议
				ConvertCaptionUtils.convertCaptionField(pTable, entity);
				ObjectMapper mapper = new ObjectMapper();
				String userMapJson = mapper.writeValueAsString(entity);

//				BpmTransactionManager.singleRef.StopTransactions(true);
				pTable.stopEditing(true);

				return userMapJson;
			} catch (Exception e){
//				BpmTransactionManager.singleRef.StopTransactions(false);
				pTable.stopEditing(false);
				throw e;
			}
		}else{
			return returnString;
		}
	}

	/**
	 * 保存字典
	 * @param tableName
	 * @param row
	 */
	private String saveDomain(String tableName, RowBase entity){

		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);
		RowBase newEntity = new RowBase();
		Object obj = null;

		Set<String> keys = entity.keySet();
		for(String key : keys){
			String newKey = "";
			if(key.equals(IDomain.ID)){
				newKey = pTable.getIDFieldName();
			} else if(key.equals(IDomain.PID)){
				newKey = pTable.getPIDFieldName();
			} else if(key.equals(IDomain.DOMAINCODE)){
				newKey = pTable.getCodeFieldName();
			} else if(key.equals(IDomain.DOMAINCAPTION)){
				newKey = pTable.getCaptionFieldName();
			} else if(key.equals(IDomain.ORDER)){
				newKey = pTable.getOrderFieldName();
			} else if(key.equals(IDomain.JB)){
				newKey = pTable.getLevelFieldName();
			} else if(key.equals(IDomain.ISCHILD)){
				newKey = pTable.getIsChildFieldName();
			} else if(key.equals(IDomain.DOMAINNAME)){
				newKey = pTable.getDomainFieldName();
			} else if(key.equals(IDomain.ISUSER)){
				newKey = pTable.getIsUsedFieldName();
			} else if(key.equals(IDomain.ISEDIT)){
				newKey = pTable.getIsEditFieldName();
			} else if(key.equals(IDomain.UNIT)){
				newKey = pTable.getUnitFieldName();
			} else {
				newKey = key;
			}

			if(!StringUtils.IsNullOrSpace(newKey)){
				obj = entity.getValue(key);
				newEntity.setValue(newKey, obj);
			}
		}
		pTable.startEditing();
		try{
			JSONObject jsonObejct = JSONObject.fromObject(entity);

			pTable.save(newEntity);
			pTable.stopEditing(true);

			return jsonObejct.toString();
		} catch (Exception e){
			pTable.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 递归取子表
	 *
	 * @param objs
	 * @param rowBase
	 * @return
	 */
	@SuppressWarnings("unchecked")
	private RowBase getDataSource(JSONObject objs, RowBase rowBase) {
		JSONObject childValues = objs;
		Set<String> childTables = childValues.keySet();
		// 收集子表记录
		HashMap<String, List<RowBase>> childHashMap = new HashMap<String, List<RowBase>>();
		for (String chidlTable : childTables) {
			List<RowBase> childRowBases = new ArrayList<RowBase>();
			JSONArray list2 = (JSONArray) childValues.get(chidlTable);
			for (int i = 0; i < list2.size(); i++) {
				JSONObject jo = (JSONObject) list2.get(i);
				RowBase childRowBase = (RowBase) JSONObject.toBean(jo, RowBase.class);
				if(childRowBase.containsKey("childValues")){
					childRowBase.remove("childValues");
				}

				// 递归取子表
				if (!(jo.get("childValues") instanceof JSONNull)) {
					JSONObject childValuesObj = JSONObject.fromObject(jo.get("childValues"));
					getDataSource(childValuesObj, childRowBase);
				}
				childRowBases.add(childRowBase);
			}
			childHashMap.put(chidlTable, childRowBases);
		}
		rowBase.setChildValues(childHashMap);
		return rowBase;
	}

//	/**
//	 * 递归存子表
//	 * 
//	 * @param objs
//	 * @param rowBase
//	 * @return
//	 */
//	private void setDataSource(RowBase rowBase, JSONObject objs) {
//		if(rowBase.getChildValues()==null || rowBase.getChildValues().size()<=0){
//			return;
//		}
//		JSONObject childValues = new JSONObject();
//		HashMap<String, List<RowBase>> child = rowBase.getChildValues();
//		Set<String> keys = child.keySet();
//		for(String key : keys){
//			List<RowBase> rowlist = child.get(key);
//			JSONArray dataList = new JSONArray();
//			for(RowBase item : rowlist){
//				JSONObject data = JSONObject.fromObject(item);
//				dataList.add(data);
//				setDataSource(item, data);
//			}
//			childValues.put(key, dataList);
//		}
//		objs.put("childValues", childValues);
//	}

	/**
	 * 批量数据保存
	 *
	 * @param tableName
	 *            数据表名
	 * @param rows
	 *            记录集，Json格式数组
	 */
	public void saveList(String tableName, String rows) {
		if (StringUtils.IsNullOrSpace(tableName)
				|| StringUtils.IsNullOrSpace(rows)) {
			return;
		}
		tableName = tableName.toUpperCase();

		List<RowBase> rowList = new ArrayList<RowBase>();
		// 数据对象
		JSONArray jsonArray = JSONArray.fromObject(rows);
		if (jsonArray.size() > 0) {
			for (int i = 0; i < jsonArray.size(); i++) {
				JSONObject rowItem = jsonArray.getJSONObject(i);
				RowBase entity = (RowBase) JSONObject.toBean(rowItem,
						RowBase.class);
				if (!(rowItem.get("childValues") instanceof JSONNull)) {
					JSONObject childValuesObj = JSONObject.fromObject(rowItem
							.get("childValues"));
					getDataSource(childValuesObj, entity);
				}
				rowList.add(entity);
			}
		}
		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);
		pTable.startEditing();
		try{
			pTable.save(rowList);
			pTable.stopEditing(true);
		} catch (Exception e){
			pTable.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 删除数据，根据数据行
	 *
	 * @param tableName
	 *            数据表名
	 * @param row
	 *            Map对象，Json格式数组
	 */
	@SuppressWarnings("unchecked")
	public void deleteByKey(String tableName, String row) {
		if (StringUtils.IsNullOrSpace(tableName)
				|| StringUtils.IsNullOrSpace(row)) {
			return;
		}
		tableName = tableName.toUpperCase();

		// 数据对象
		JSONObject queryJsonObject = JSONObject.fromObject(row);
		HashMap<String, Object> whereMap = (HashMap<String, Object>) JSONObject
				.toBean(queryJsonObject, HashMap.class);

		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);

		pTable.startEditing();
//		BpmTransactionManager.singleRef.StartTransactions();
		try{
			convertStaticField(pTable, whereMap);
			IQueryMap queryMap = new QueryMap();
			queryMap.setWhereMap(whereMap);
			pTable.delete(queryMap);
//			BpmTransactionManager.singleRef.StopTransactions(true);
			pTable.stopEditing(true);
		} catch (Exception e){
//			BpmTransactionManager.singleRef.StopTransactions(false);
			pTable.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 删除数据，根据数据行。同时处理工作流信息
	 *
	 * @param tableName
	 *            数据表名
	 * @param row
	 *            Map对象，Json格式数组
	 */
	@SuppressWarnings("unchecked")
	public void deleteByKeyInBpm(String tableName, String query, String activitiKey) {
		if (StringUtils.IsNullOrSpace(tableName)
				|| StringUtils.IsNullOrSpace(query)) {
			return;
		}
		tableName = tableName.toUpperCase();

		// 数据对象
		JSONObject queryJsonObject = JSONObject.fromObject(query);
		HashMap<String, Object> whereMap = (HashMap<String, Object>) JSONObject
				.toBean(queryJsonObject, HashMap.class);

		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);

		pTable.startEditing();
//		BpmTransactionManager.singleRef.StartTransactions();
		try{
			convertStaticField(pTable, whereMap);
			IQueryMap queryMap = new QueryMap();
			queryMap.setWhereMap(whereMap);
			// 先查询，再单个删除
			List<RowBase> rowList = pTable.getEntityList(RowBase.class, queryMap);
			if(rowList!=null){
				for(RowBase row : rowList){
					pTable.delete(row);
				}
			}
//			BpmTransactionManager.singleRef.StopTransactions(true);
			pTable.stopEditing(true);
		} catch (Exception e){
//			BpmTransactionManager.singleRef.StopTransactions(false);
			pTable.stopEditing(false);
			throw e;
		}
	}

	private void convertStaticField(ITable pTable, HashMap<String, Object> whereMap){
		if(pTable==null){
			return;
		}
		if(whereMap==null){
			return;
		}

		if((pTable.getIsCodeTable() || pTable.getIsTreeTable())
				&& pTable.getIsManageCodeTable()){
			Set<String> keys = whereMap.keySet();
			List<String> keyList = new ArrayList<String>();
			keyList.addAll(keys);
			for(String key : keyList){
				String newKey = "";
				if(key.equals(IDomain.ID)){
					newKey = pTable.getIDFieldName();
				}

				if(key.equals(IDomain.PID)){
					newKey = pTable.getPIDFieldName();
				}

				if(key.equals(IDomain.DOMAINCODE)){
					newKey = pTable.getCodeFieldName();
				}

				if(key.equals(IDomain.DOMAINCAPTION)){
					newKey = pTable.getCaptionFieldName();
				}

				if(key.equals(IDomain.ORDER)){
					newKey = pTable.getOrderFieldName();
				}

				if(key.equals(IDomain.JB)){
					newKey = pTable.getLevelFieldName();
				}

				if(key.equals(IDomain.ISCHILD)){
					newKey = pTable.getIsChildFieldName();
				}

				if(key.equals(IDomain.DOMAINNAME)){
					newKey = pTable.getDomainFieldName();
				}

				if(key.equals(IDomain.ISUSER)){
					newKey = pTable.getIsUsedFieldName();
				}

				if(key.equals(IDomain.ISEDIT)){
					newKey = pTable.getIsEditFieldName();
				}

				if(key.equals(IDomain.UNIT)){
					newKey = pTable.getUnitFieldName();
				}

				if(!StringUtils.IsNullOrSpace(newKey)){
					Object value = whereMap.get(key);
					whereMap.remove(key);
					whereMap.put(newKey, value);
				}
			}
		}
	}

	/**
	 * 获取实体对象，根据主键
	 * @param tableName
	 * @param key
	 * @return
	 */
	public String getEntityByKey(String tableName, String key) {
		if (StringUtils.IsNullOrSpace(tableName)
				|| StringUtils.IsNullOrSpace(key)) {
			return null;
		}
		tableName = tableName.toUpperCase();
		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);

		IQueryMap queryMap = new QueryMap();
		queryMap.setAddCaptionField(true);
		queryMap.getWhereMap().put(pTable.getGUIDFieldName(), key);
		RowBase row = pTable.getEntity(RowBase.class, queryMap);

		JSONObject data = JSONObject.fromObject(row);
		return data.toString();
	}

	/**
	 * 根据分页条件获取数据行
	 *
	 * @param tableName
	 *            数据表名
	 * @param query
	 *            查询条件，Map对象，Json格式
	 * @param order
	 *            排序条件，Map对象，Json格式
	 * @param pageSize
	 *            最大分页大小
	 * @param pageIndex
	 *            分页索引
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String getPageRows(String tableName, String query, String order,
							  int pageSize, int pageIndex) {
		if (StringUtils.IsNullOrSpace(tableName)) {
			return null;
		}
		tableName = tableName.toUpperCase();

		// 获取查询条件
		JSONObject queryJsonObject = JSONObject.fromObject(query);
		HashMap<String, Object> whereMap = (HashMap<String, Object>) JSONObject
				.toBean(queryJsonObject, HashMap.class);

		// 获取排序条件
		JSONObject orderJsonObject = JSONObject.fromObject(order);
		HashMap<String, Object> orderMap = (HashMap<String, Object>) JSONObject
				.toBean(orderJsonObject, HashMap.class);

		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);
		IQueryMap queryMap = new QueryMap();
		queryMap.setAddCaptionField(true);
		queryMap.setWhereMap(whereMap);
		queryMap.setOrderByMap(orderMap);
		PageInfo pageInfo = new PageInfo();
		pageInfo.setPageIndex(pageIndex);
		pageInfo.setPageSize(pageSize);
		pageInfo.setRefreshRowCount(true);

		List<RowBase> rows = pTable.pageSelect(RowBase.class, queryMap,
				pageInfo);
		if (rows != null && rows.size() >= 0) {
			JSONArray data = JSONArray.fromObject(rows);
			JSONObject pageInformation = JSONObject.fromObject(pageInfo);
			JSONObject resultObject = new JSONObject();
			//分页信息
			resultObject.put("pageInfo", pageInformation);
			//查询结果
			resultObject.put("data", data);
			JSONArray paramInfo = new JSONArray();
			paramInfo.add(queryJsonObject);
			paramInfo.add(orderJsonObject);
			JSONObject tableNameJSON = new JSONObject();
			tableNameJSON.put("tableName",tableName);
			paramInfo.add(tableNameJSON);
			//查询参数信息
			resultObject.put("paramInfo", paramInfo);

			return resultObject.toString();
		} else {
			return null;
		}
	}

	/**
	 * 获取字典域，返回所有字典数据
	 *
	 * @param tableName
	 * @param domianName
	 * @return
	 */
	public String getDomainsEx(String tableName, String domianName, boolean convertStaticField) {
		if (StringUtils.IsNullOrSpace(tableName)) {
			return null;
		}
		if (StringUtils.IsNullOrSpace(domianName)) {
			domianName ="";
		}
		tableName = tableName.toUpperCase();
		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		IDomain pTable = tableFactory.openDomain(tableName, domianName);
		List<Map<String, Object>> result = pTable.getDatasEx2(convertStaticField);

		if (result != null && result.size() > 0) {
			JSONArray arrayObject = JSONArray.fromObject(result);
			return arrayObject.toString();
		} else {
			return null;
		}
	}

	/**
	 * 获取字典域，只返回id,text数据
	 *
	 * @param tableName
	 * @param domianName
	 * @param filter 字典过滤条件
	 * @param addPinYin 是否添加拼音
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String getDomains(String tableName, String domianName,String filter,String addPinYin) {
		if (StringUtils.IsNullOrSpace(tableName)) {
			return null;
		}
		tableName = tableName.toUpperCase();
		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		IDomain pTable = tableFactory.openDomain(tableName, domianName);
		List<TreeDataNode> result = new ArrayList<TreeDataNode>();
		if (!StringUtils.IsNullOrSpace(filter)) {
			// 按过滤条件过滤字典
			JSONObject filterJsonObject = JSONObject.fromObject(filter);
			HashMap<String, Object> filterMap = (HashMap<String, Object>) JSONObject
					.toBean(filterJsonObject, HashMap.class);
			//TODO 追加政区字典权限过滤
			HashMap<String, String> sqlCache = (HashMap<String, String>) SessionFactory.getSession()
					.getObject(ISessionProvider.SQLList);
			UserEntity userEntity = (UserEntity) SessionFactory.getSession().getObject(ISessionProvider.UserEntity);
			if(userEntity!=null && !userEntity.getIsSuperAdmin()){
				if(sqlCache.containsKey("DATA_DEFULATDOMAIN") && "政区字典".equals(domianName)){
					String nextOrgid=userEntity.getOrgID();//.substring(0,2);
					if(nextOrgid.endsWith("0000") && nextOrgid.length()==6){
						nextOrgid=nextOrgid.substring(0,2);
					}else if(nextOrgid.endsWith("00") && nextOrgid.length()==6){
						nextOrgid=nextOrgid.substring(0,4);
					}else{
						int rootId = Integer.valueOf((String)filterMap.get("S_PID"));
						if(rootId > 1){
							nextOrgid=nextOrgid.substring(0,6);
						}else{
							nextOrgid=nextOrgid.substring(0,4);
						}

					}
					result = pTable.getDatasEx(filterMap,"S_DOMAINCODE",nextOrgid);
				}
				else{
					result = pTable.getDatasEx(filterMap);
				}
			}else{
				result = pTable.getDatasEx(filterMap);
			}
		}else{
			result = pTable.getDatasEx();
		}

		if("true".equalsIgnoreCase(addPinYin)){
			for (TreeDataNode node : result) {
				String text = node.getText();
				String[] headPy = PinYinUtil.getHeadByString(text,false);
				node.setText_py_(PinYinUtil.stringArrayToString(headPy));
				node.setText_fullPy_(PinYinUtil.hanziToPinyin(text, ""));
			}
		}

		if (result != null && result.size() > 0) {
			JSONArray arrayObject = JSONArray.fromObject(result);
			return arrayObject.toString();
		} else {
			return null;
		}
	}

	/**
	 * 获取树型数据
	 *
	 * @param tableName
	 * @param query
	 * @param order
	 * @param pId
	 * @param jbs
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public String getTreeData(String tableName, String query, String order,
							  String pId, String jbs, String domainName, int pageSize, int pageIndex) {
//		if (StringUtils.IsNullOrSpace(tableName)) {
//			return null;
//		}
//		tableName = tableName.toUpperCase();
//
//		// 获取查询条件
//		HashMap<String, Object> whereMap = new HashMap<String, Object>();
//		if (!StringUtils.IsNullOrSpace(query)) {
//			JSONObject queryJsonObject = JSONObject.fromObject(query);
//			whereMap = (HashMap<String, Object>) JSONObject
//					.toBean(queryJsonObject, HashMap.class);
//		}
//
//		// 获取排序条件
//		JSONObject orderJsonObject = JSONObject.fromObject(order);
//		HashMap<String, Object> orderMap = (HashMap<String, Object>) JSONObject
//				.toBean(orderJsonObject, HashMap.class);
//
//		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
//				.getBean("TableFactory");
//		ITable pTable = tableFactory.openTable(tableName);
//		IQueryMap queryMap = new QueryMap();
//		queryMap.setAddCaptionField(true);
//		queryMap.setOrderByMap(orderMap);
//
//		List<Map<String, Object>> result = null;
//		// 指定的PID，直接使用PID
//		if (!StringUtils.IsNullOrSpace(pId)) {
//			queryMap.getWhereMap().put(pTable.getPIDFieldName(), pId);
//			List<RowBase> rows = pTable.getEntityList(RowBase.class, queryMap);
//			result = TreeDataUtils.GetTreeData(rows, null, null,
//					pTable.getIsChildFieldName(), pTable.getCodeFieldName(),
//					pTable.getCaptionFieldName());
//		} else {
//			queryMap.setWhereMap(whereMap);
//
//			// 带有原始查询条件，使用分页查询
//			if (queryMap.getWhereObject().keySet().size() > 0) {
//				PageInfo pageInfo = new PageInfo();
//				pageInfo.setPageIndex(pageIndex);
//				pageInfo.setPageSize(pageSize);
//				List<RowBase> rows = pTable.pageSelect(RowBase.class, queryMap,
//						pageInfo);
//				result = TreeDataUtils
//						.GetTreeData(rows, null, null,
//								pTable.getIsChildFieldName(),
//								pTable.getCodeFieldName(),
//								pTable.getCaptionFieldName());
//			}else if(!StringUtils.IsNullOrSpace(pTable.getDomainFieldName())
//					&& !StringUtils.IsNullOrSpace(domainName)){
//				//设置字典域时，加上字典域条件
//				return getDomains(tableName, domainName, query,null);
//			} else {
//				// 没条件时，加上只加载指定级别数据
//				if (!StringUtils.IsNullOrSpace(pTable.getLevelFieldName())
//						&& !StringUtils.IsNullOrSpace(jbs)) {
//					queryMap.getWhereMap().put(
//							pTable.getLevelFieldName() + ":in", jbs);
//				}
//				List<RowBase> rows = pTable.getEntityList(RowBase.class,
//						queryMap);
//				result = TreeDataUtils
//						.GetTreeData(rows, pTable.getIDFieldName(),
//								pTable.getPIDFieldName(),
//								pTable.getIsChildFieldName(),
//								pTable.getCodeFieldName(),
//								pTable.getCaptionFieldName());
//			}
//		}
//
//		if (result != null && result.size() > 0) {
//			JSONArray arrayObject = JSONArray.fromObject(result);
//			return arrayObject.toString();
//		} else {
//			return null;
//		}
		return null;
	}

	/**
	 * 获取子表数据
	 *
	 * @param tableName
	 *            主表名称
	 * @param row
	 *            主表记录
	 * @param childTables
	 *            子表名称集
	 * @return
	 */
	public String getChildData(String tableName, String row, String childTables) {
		if (StringUtils.IsNullOrSpace(tableName)
				|| StringUtils.IsNullOrSpace(row)
				|| StringUtils.IsNullOrSpace(childTables)) {
			return null;
		}
		tableName = tableName.toUpperCase();

		// 获取排序条件
		JSONObject orderJsonObject = JSONObject.fromObject(row);
		RowBase pRow = (RowBase) JSONObject.toBean(orderJsonObject,
				RowBase.class);

		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);

		String[] childs = childTables.split(",");
		for (String item : childs) {
			HashMap<String, Object> orderByMap = new HashMap<String, Object>();
			// 填充子表
			RelationOption.FillEntityChild(pTable, pRow, item, orderByMap, true);
		}
		HashMap<String, List<RowBase>> childValues = pRow.getChildValues();
		if (childValues == null || childValues.size() <= 0) {
			return null;
		} else {
			JSONArray arrayObject = JSONArray.fromObject(childValues);
			return arrayObject.toString();
		}
	}

	/**
	 * 获取子表数据
	 *
	 * @param tableName
	 *            主表名称
	 * @param row
	 *            主表记录
	 * @param childTables
	 *            子表名称集
	 * @return
	 */
	public String getChildDataEx(String tableName, String row, String childTables, String childOrder) {
		if (StringUtils.IsNullOrSpace(tableName)
				|| StringUtils.IsNullOrSpace(row)
				|| StringUtils.IsNullOrSpace(childTables)) {
			return null;
		}
		tableName = tableName.toUpperCase();

		// 获取排序条件
		JSONObject orderJsonObject = JSONObject.fromObject(row);
		RowBase pRow = (RowBase) JSONObject.toBean(orderJsonObject,
				RowBase.class);

		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);

		String[] childs = childTables.split(",");
		String[] childOrders = null;
		if(!StringUtils.IsNullOrSpace(childOrder)){
			childOrders = childOrder.split(",");
		}

		for(int i=0;i<childs.length;i++){
			String cTable = childs[i];
			// 处理排序BPM_TASK_CONFIG:I_ORDER:1
			HashMap<String, Object> orderByMap = new HashMap<String, Object>();
			if(childOrders!=null){
				if(i<childOrders.length){
					if(!StringUtils.IsNullOrSpace(childOrders[i])){
						String[] msgs = childOrders[i].split(":");
						if(msgs.length>=2){
							for(int j=0;j<msgs.length;j+=2){
								orderByMap.put(msgs[j], msgs[j+1]);
							}
						}
					}
				}
			}
			// 填充子表
			RelationOption.FillEntityChild(pTable, pRow, cTable, orderByMap, true);
		}

		HashMap<String, List<RowBase>> childValues = pRow.getChildValues();
		if (childValues == null || childValues.size() <= 0) {
			return null;
		} else {
			JSONArray arrayObject = JSONArray.fromObject(childValues);
			return arrayObject.toString();
		}
	}

	/**
	 * 填充中间表子表数据，并根据中间表与关联的另外一张主表将外键关系，将另外一张主表的信息一起填充给中间子表记录
	 * 如，用户表，用户角色表，角色表。当获取用户角色表时，可将角色表的信息一起查询出来，并给中间表子间填充
	 * 如果另外一张主表中的字段在中间表中存在，则另外一张主表的字段改为字段名+"_OO"
	 * @param tableName
	 * @param row
	 * @param childTables			子表，如：table1,table2
	 * @param childOrder			子表排序，如：I_ORDER:1:ORDERFIELD2:0,I_ORDER:0，用，分开顺序和子表的顺序一样
	 * @param tagetTableName		中间表关联表对象，如：tagetTableName:childField:tagetField:childField1:tagetField1,tagetTableName:childField:tagetField:childField1:tagetField1
	 * @return
	 */
	public String getChildDataEx2(String tableName, String row,
								  String childTables, String childOrder,
								  String tagetTableName) {
		if (StringUtils.IsNullOrSpace(tableName)
				|| StringUtils.IsNullOrSpace(row)
				|| StringUtils.IsNullOrSpace(childTables)) {
			return null;
		}
		tableName = tableName.toUpperCase();

		// 获取排序条件
		JSONObject orderJsonObject = JSONObject.fromObject(row);
		RowBase pRow = (RowBase) JSONObject.toBean(orderJsonObject,
				RowBase.class);

		ITableFactory tableFactory = (ITableFactory) SpringBeanFactory
				.getBean("TableFactory");
		ITable pTable = tableFactory.openTable(tableName);

		String[] childs = childTables.split(",");
		String[] childOrders = null;
		if(!StringUtils.IsNullOrSpace(childOrder)){
			childOrders = childOrder.split(",");
		}

		String[] tagetTableNames = null;
		if(!StringUtils.IsNullOrSpace(tagetTableName)){
			tagetTableNames = tagetTableName.split(",");
		}

		for(int i=0;i<childs.length;i++){
			String cTable = childs[i];

			// 处理排序BPM_TASK_CONFIG:I_ORDER:1
			HashMap<String, Object> orderByMap = new HashMap<String, Object>();
			if(childOrders!=null){
				if(i<childOrders.length){
					if(!StringUtils.IsNullOrSpace(childOrders[i])){
						String[] msgs = childOrders[i].split(":");
						if(msgs.length>=2){
							for(int j=0;j<msgs.length;j+=2){
								orderByMap.put(msgs[j], msgs[j+1]);
							}
						}
					}
				}
			}

			String tName = null;
			HashMap<String, String> relation = new HashMap<String, String>();
			if(tagetTableNames!=null){
				if(i<tagetTableNames.length){
					String[] tagetTables = tagetTableNames[i].split(":");
					if(tagetTables.length>=3){
						tName = tagetTables[0];
						for(int j=1;j<tagetTables.length;j+=2){
							relation.put(tagetTables[j], tagetTables[j+1]);
						}
					}
				}
			}

			if(relation.size()>0){
				// 填充子表
				RelationOption.FillEntityChild(pTable, pRow, cTable, tName, relation, orderByMap, true);
			}
		}

		HashMap<String, List<RowBase>> childValues = pRow.getChildValues();
		if (childValues == null || childValues.size() <= 0) {
			return null;
		} else {
			JSONArray arrayObject = JSONArray.fromObject(childValues);
			return arrayObject.toString();
		}
	}

	/**
	 * 获取最后修改时间
	 */
	@Override
	public long getLastModified(HttpServletRequest request, Object formHandler) {
		return -1;
	}

	/**
	 * 获取当前的数据和Model
	 */
	@Override
	public ModelAndView handle(HttpServletRequest request,
							   HttpServletResponse response, Object formHandler) {
		try {
			// 获取URL
			String lookupPath = urlHelper.getLookupPathForRequest(request);
			lookupPath = lookupPath.replace(".do", "");
			String[] urls = lookupPath.split("/");
			if (urls.length != 4) {
				return null;
			}

			FormHandler handler = (FormHandler) formHandler;
			// 获取数据表
			String tableName = urls[2];
			// 方法名称
			String methodName = urls[3];
			String returnValue = null;

			if (methodName.equals("save")) {
				String rowString = request.getParameter("data");
				returnValue = handler.save(tableName, rowString);
			} else if (methodName.equals("saveList")) {
				String rowString = request.getParameter("data");
				handler.saveList(tableName, rowString);
			} else if (methodName.equals("deleteByKey")) {
				String rowString = request.getParameter("data");
				handler.deleteByKey(tableName, rowString);
			} else if (methodName.equals("deleteByKeyInBpm")) {
				String rowString = request.getParameter("data");
				String activitiKey = request.getParameter("akey");
				handler.deleteByKeyInBpm(tableName, rowString, activitiKey);
			}else if (methodName.equals("getEntityByKey")) {
				String rowString = request.getParameter("data");
				returnValue = handler.getEntityByKey(tableName, rowString);
			} else if (methodName.equals("getPageRows")) {
				String queryData = request.getParameter("queryData");
				String orderData = request.getParameter("orderData");
				String pageSize = request.getParameter("pageSizeData");
				String pageIndex = request.getParameter("pageIndexData");
				int pageSizeInt = 25;
				if (!StringUtils.IsNullOrSpace(pageSize)) {
					pageSizeInt = Integer.parseInt(pageSize);
				}
				int pageIndexInt = 1;
				if (!StringUtils.IsNullOrSpace(pageIndex)) {
					pageIndexInt = Integer.parseInt(pageIndex);
				}

				returnValue = handler.getPageRows(tableName, queryData,
						orderData, pageSizeInt, pageIndexInt);
			} else if (methodName.equals("getTreeData")) {
				String queryData = request.getParameter("queryData");
				String orderData = request.getParameter("orderData");
				String pId = request.getParameter("pID");
				String jbs = request.getParameter("JBs");
				String domainName = request.getParameter("domainName");
				String pageSize = request.getParameter("pageSizeData");
				String pageIndex = request.getParameter("pageIndexData");
				int pageSizeInt = 25;
				if (!StringUtils.IsNullOrSpace(pageSize)) {
					pageSizeInt = Integer.parseInt(pageSize);
				}
				int pageIndexInt = 1;
				if (!StringUtils.IsNullOrSpace(pageIndex)) {
					pageIndexInt = Integer.parseInt(pageIndex);
				}
				returnValue = handler.getTreeData(tableName, queryData,
						orderData, pId, jbs,domainName, pageSizeInt, pageIndexInt);
			} else if (methodName.equals("getDomains")) {
				String rowString = request.getParameter("data");
				String filter =request.getParameter("filterObject");
				String addPinYin = request.getParameter("addPinYin");
				returnValue = handler.getDomains(tableName, rowString,filter,addPinYin);
			} else if (methodName.equals("getDomainsEx")) {
				String rowString = request.getParameter("data");
				String convertStatic = request.getParameter("convertStatic");
				boolean cStatic = false;
				if (!StringUtils.IsNullOrSpace(convertStatic)) {
					cStatic = Boolean.parseBoolean(convertStatic);
				}
				returnValue = handler.getDomainsEx(tableName, rowString, cStatic);
			} else if (methodName.equals("getChildData")) {
				String row = request.getParameter("data");
				String childTables = request.getParameter("childTables");
				returnValue = handler.getChildData(tableName, row, childTables);
			} else if (methodName.equals("getChildDataEx")) {
				String row = request.getParameter("data");
				String childTables = request.getParameter("childTables");
				String childOrders = request.getParameter("childOrders");
				returnValue = handler.getChildDataEx(tableName, row, childTables, childOrders);
			} else if (methodName.equals("getChildDataEx2")) {
				String row = request.getParameter("data");
				String childTables = request.getParameter("childTables");
				String childOrders = request.getParameter("childOrders");
				String tagetTableName = request.getParameter("tagetTableNames");
				returnValue = handler.getChildDataEx2(tableName, row, childTables, childOrders, tagetTableName);
			}

			if (returnValue == null) {
				return null;
			} else {
				// 向浏览器发送一个响应头，设置浏览器的解码方式为UTF-8
				response.setHeader("Content-type", "text/html;charset=UTF-8");
				OutputStream stream = response.getOutputStream();
				stream.write(returnValue.getBytes("UTF-8"));
				return null;
			}
		} catch (DuplicateKeyException dx){
			dx.printStackTrace();
			getError(response, "主键冲突。");
			return null;
		} catch (UncategorizedSQLException ux){
			ux.printStackTrace();
			getError(response, "数据执行错误。");
			return null;
		} catch (UniqueCheckException ux){
			ux.printStackTrace();
			getError(response, ux.getMessage());
			return null;
		} catch (VersionCheckException ux){
			ux.printStackTrace();
			getError(response, ux.getMessage());
			return null;
		} catch (FieldIsNullException e){
			e.printStackTrace();
			getError(response,  e.getMessage());
			return null;
		} catch (RegexNotMatchException e){
			e.printStackTrace();
			getError(response, e.getMessage());
			return null;
		} catch (StringLengthException e){
			e.printStackTrace();
			getError(response, e.getMessage());
			return null;
		} catch (Exception ex) {
			ex.printStackTrace();
			getError(response, "数据执行错误。");
			return null;
		}
	}

	private void getError(HttpServletResponse response, String msg) {
		// 向浏览器发送一个响应头，设置浏览器的解码方式为UTF-8
		response.setHeader("Content-type", "text/html;charset=UTF-8");
		try {
			OutputStream stream = response.getOutputStream();
			stream.write(msg.getBytes("UTF-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Override
	public boolean supports(Object obj) {
		if (obj instanceof FormHandler) {
			return true;
		} else {
			return false;
		}
	}
}